<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AI对话界面</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#165DFF',
                        secondary: '#0FC6C2',
                        neutral: {
                            100: '#F5F7FA',
                            200: '#E5E6EB',
                            300: '#C9CDD4',
                            400: '#86909C',
                            500: '#4E5969',
                            600: '#272E3B',
                            700: '#1D2129',
                        }
                    },
                    fontFamily: {
                        inter: ['Inter', 'sans-serif'],
                    },
                    boxShadow: {
                        'dropdown': '0 4px 20px rgba(0, 0, 0, 0.1)',
                        'card': '0 2px 12px rgba(0, 0, 0, 0.08)',
                    }
                },
            }
        }
    </script>
    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .scrollbar-hide::-webkit-scrollbar {
                display: none;
            }
            .scrollbar-hide {
                -ms-overflow-style: none;
                scrollbar-width: none;
            }
            .chat-height {
                height: calc(100vh - 12rem);
            }
            .mobile-chat-height {
                height: calc(100vh - 14rem);
            }
        }
    </style>
</head>
<body class="bg-neutral-100 font-inter text-neutral-700">
<div class="min-h-screen flex flex-col">
    <!-- 顶部导航栏 -->
    <header class="bg-white border-b border-neutral-200 shadow-sm">
        <div class="container mx-auto px-4 py-3 flex items-center justify-between">
            <div class="flex items-center space-x-2">
                <i class="fa fa-comments text-primary text-2xl"></i>
                <h1 class="text-xl font-bold text-neutral-700">AI对话助手</h1>
            </div>

            <!-- API地址选择器 -->
            <div class="relative" id="apiSelectorContainer">
                <button id="apiSelectorButton" class="flex items-center space-x-1.5 px-2.5 py-1 rounded-md border border-neutral-200 bg-neutral-100 text-neutral-700 hover:bg-neutral-200 transition-colors duration-200">
                    <i class="fa fa-server text-sm"></i>
                    <span id="currentApiName" class="text-sm">默认API</span>
                    <i class="fa fa-chevron-down text-xs"></i>
                </button>

                <!-- API管理下拉菜单 -->
                <div id="apiDropdown" class="absolute right-0 mt-2 w-80 bg-white rounded-lg shadow-dropdown overflow-hidden z-50 hidden">
                    <!-- 下拉菜单头部 -->
                    <div class="px-4 py-3 bg-neutral-50 border-b border-neutral-200 flex justify-between items-center">
                        <h3 class="font-medium text-neutral-700">API地址管理</h3>
                        <button id="addApiButton" class="text-primary hover:text-primary/80 transition-colors">
                            <i class="fa fa-plus-circle"></i> 添加
                        </button>
                    </div>

                    <!-- API列表表格 -->
                    <div class="max-h-60 overflow-y-auto scrollbar-hide">
                        <table class="w-full text-sm">
                            <thead>
                            <tr class="bg-neutral-50 text-neutral-500">
                                <th class="px-4 py-2 text-left text-xs font-medium uppercase tracking-wider">模块名称</th>
                                <th class="px-4 py-2 text-left text-xs font-medium uppercase tracking-wider">端口</th>
                                <th class="px-4 py-2 text-left text-xs font-medium uppercase tracking-wider">地址</th>
                                <th class="px-4 py-2 text-center text-xs font-medium uppercase tracking-wider">操作</th>
                            </tr>
                            </thead>
                            <tbody id="apiList">
                            <!-- API地址将通过JavaScript动态添加 -->
                            </tbody>
                        </table>
                    </div>

                    <!-- 下拉菜单底部 -->
                    <div class="px-4 py-2 bg-neutral-50 border-t border-neutral-200 text-xs text-neutral-500">
                        提示: 选择一个API地址用于发送请求
                    </div>
                </div>
            </div>
        </div>
    </header>

    <!-- 主要内容区域 -->
    <main class="flex-grow container mx-auto px-4 py-4">
        <!-- 聊天消息区域 -->
        <div class="bg-white rounded-xl shadow-card overflow-hidden">
            <div id="chatContainer" class="chat-height md:chat-height overflow-y-auto p-4 space-y-4">
                <!-- 系统消息 -->
                <div class="flex items-start space-x-3">
                    <div class="w-8 h-8 rounded-full bg-primary/10 flex items-center justify-center text-primary">
                        <i class="fa fa-info-circle"></i>
                    </div>
                    <div class="flex-1 bg-neutral-50 rounded-lg p-3">
                        <p class="text-neutral-600">欢迎使用AI对话助手！请在下方输入框中输入您的问题。</p>
                    </div>
                </div>

                <!-- 用户和AI消息将通过JavaScript动态添加 -->
            </div>

            <!-- 分隔线 -->
            <div class="border-t border-neutral-200"></div>

            <!-- 输入区域 -->
            <div class="p-4">
                <form id="chatForm" class="flex space-x-3">
            <textarea
                    id="userInput"
                    class="flex-grow px-4 py-3 rounded-lg border border-neutral-200 focus:border-primary focus:ring-1 focus:ring-primary focus:outline-none resize-none transition-all duration-200"
                    rows="1"
                    placeholder="请输入您的问题..."
            ></textarea>
                    <button
                            type="submit"
                            class="px-4 py-3 bg-primary text-white rounded-lg hover:bg-primary/90 focus:ring-2 focus:ring-primary/50 focus:outline-none transition-all duration-200 flex items-center justify-center"
                    >
                        <i class="fa fa-paper-plane mr-2"></i> 发送
                    </button>
                </form>
                <div class="text-xs text-neutral-400 mt-2">
                    提示: 按Enter发送消息，Shift+Enter换行
                </div>
            </div>
        </div>
    </main>

    <!-- 页脚 -->
    <footer class="bg-white border-t border-neutral-200 py-4">
        <div class="container mx-auto px-4 text-center text-xs text-neutral-500">
            <p>© 2025 AI对话助手 | 所有API请求使用GET方法</p>
        </div>
    </footer>
</div>

<!-- 添加/编辑API地址模态框 -->
<div id="apiModal" class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 hidden">
    <div class="bg-white rounded-xl shadow-lg w-full max-w-md mx-4 transform transition-all duration-300 scale-95 opacity-0" id="modalContent">
        <div class="px-6 py-4 border-b border-neutral-200 flex justify-between items-center">
            <h3 class="text-lg font-medium text-neutral-700" id="modalTitle">添加API地址</h3>
            <button id="closeModal" class="text-neutral-400 hover:text-neutral-600">
                <i class="fa fa-times"></i>
            </button>
        </div>
        <div class="p-6">
            <form id="apiForm">
                <input type="hidden" id="apiId" value="">
                <div class="space-y-4">
                    <div>
                        <label for="apiName" class="block text-sm font-medium text-neutral-700 mb-1">模块名称</label>
                        <input
                                type="text"
                                id="apiName"
                                class="w-full px-3 py-2 border border-neutral-200 rounded-md focus:border-primary focus:ring-1 focus:ring-primary focus:outline-none transition-all duration-200"
                                placeholder="例如: client"
                        >
                    </div>
                    <div>
                        <label for="apiPort" class="block text-sm font-medium text-neutral-700 mb-1">端口</label>
                        <input
                                type="number"
                                id="apiPort"
                                class="w-full px-3 py-2 border border-neutral-200 rounded-md focus:border-primary focus:ring-1 focus:ring-primary focus:outline-none transition-all duration-200"
                                placeholder="例如: 10001"
                        >
                    </div>
                    <div>
                        <label for="apiPath" class="block text-sm font-medium text-neutral-700 mb-1">具体地址</label>
                        <input
                                type="text"
                                id="apiPath"
                                class="w-full px-3 py-2 border border-neutral-200 rounded-md focus:border-primary focus:ring-1 focus:ring-primary focus:outline-none transition-all duration-200"
                                placeholder="例如: /chat"
                        >
                    </div>
                </div>
                <div class="mt-6 flex justify-end space-x-3">
                    <button type="button" id="cancelApiForm" class="px-4 py-2 border border-neutral-200 rounded-md text-neutral-700 hover:bg-neutral-50 transition-colors duration-200">
                        取消
                    </button>
                    <button type="submit" class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary/90 focus:ring-2 focus:ring-primary/50 focus:outline-none transition-all duration-200">
                        保存
                    </button>
                </div>
            </form>
        </div>
    </div>
</div>

<script>
    // 初始化API列表
    let apiList = [
        { id: 1, name: "默认API", port: 10001, path: "/chat" },
        { id: 2, name: "备用API", port: 10002, path: "/chat" },
        { id: 3, name: "测试API", port: 10003, path: "/test" }
    ];

    // 当前选中的API索引
    let currentApiIndex = 0;

    // DOM元素
    const apiSelectorButton = document.getElementById('apiSelectorButton');
    const apiDropdown = document.getElementById('apiDropdown');
    const apiListElement = document.getElementById('apiList');
    const addApiButton = document.getElementById('addApiButton');
    const apiModal = document.getElementById('apiModal');
    const modalContent = document.getElementById('modalContent');
    const closeModal = document.getElementById('closeModal');
    const cancelApiForm = document.getElementById('cancelApiForm');
    const apiForm = document.getElementById('apiForm');
    const chatForm = document.getElementById('chatForm');
    const userInput = document.getElementById('userInput');
    const chatContainer = document.getElementById('chatContainer');

    // 渲染API列表
    function renderApiList() {
        apiListElement.innerHTML = '';

        apiList.forEach((api, index) => {
            const isSelected = index === currentApiIndex;
            const row = document.createElement('tr');
            row.className = `hover:bg-neutral-50 ${isSelected ? 'bg-primary/5' : ''} transition-colors duration-150`;

            row.innerHTML = `
          <td class="px-4 py-3 whitespace-nowrap">
            <div class="font-medium text-neutral-700 ${isSelected ? 'text-primary font-semibold' : ''}">${api.name}</div>
          </td>
          <td class="px-4 py-3 whitespace-nowrap">
            <div class="text-neutral-600">${api.port}</div>
          </td>
          <td class="px-4 py-3 whitespace-nowrap">
            <div class="text-neutral-600">${api.path}</div>
          </td>
          <td class="px-4 py-3 whitespace-nowrap text-center text-sm">
            <button class="edit-api text-primary hover:text-primary/80 mr-2" data-index="${index}">
              <i class="fa fa-pencil"></i>
            </button>
            <button class="delete-api text-red-500 hover:text-red-600" data-index="${index}">
              <i class="fa fa-trash"></i>
            </button>
          </td>
        `;

            // 添加选择API事件
            row.addEventListener('click', (e) => {
                if (!e.target.closest('button')) {
                    selectApi(index);
                }
            });

            apiListElement.appendChild(row);
        });

        // 更新当前API名称显示
        document.getElementById('currentApiName').textContent = apiList[currentApiIndex].name;

        // 添加编辑和删除事件
        document.querySelectorAll('.edit-api').forEach(button => {
            button.addEventListener('click', () => {
                const index = parseInt(button.getAttribute('data-index'));
                editApi(index);
            });
        });

        document.querySelectorAll('.delete-api').forEach(button => {
            button.addEventListener('click', () => {
                const index = parseInt(button.getAttribute('data-index'));
                deleteApi(index);
            });
        });
    }

    // 选择API
    function selectApi(index) {
        currentApiIndex = index;
        renderApiList();
        toggleApiDropdown();
    }

    // 添加新API
    function addApi() {
        document.getElementById('modalTitle').textContent = '添加API地址';
        document.getElementById('apiId').value = '';
        document.getElementById('apiName').value = '';
        document.getElementById('apiPort').value = '';
        document.getElementById('apiPath').value = '';
        openModal();
    }

    // 编辑API
    function editApi(index) {
        const api = apiList[index];
        document.getElementById('modalTitle').textContent = '编辑API地址';
        document.getElementById('apiId').value = index;
        document.getElementById('apiName').value = api.name;
        document.getElementById('apiPort').value = api.port;
        document.getElementById('apiPath').value = api.path;
        openModal();
    }

    // 删除API
    function deleteApi(index) {
        if (apiList.length <= 1) {
            alert('至少保留一个API地址');
            return;
        }

        if (confirm(`确定要删除 "${apiList[index].name}" 吗？`)) {
            apiList.splice(index, 1);
            if (currentApiIndex >= apiList.length) {
                currentApiIndex = apiList.length - 1;
            }
            renderApiList();
        }
    }

    // 切换API下拉菜单显示/隐藏
    function toggleApiDropdown() {
        apiDropdown.classList.toggle('hidden');

        // 添加动画效果
        if (!apiDropdown.classList.contains('hidden')) {
            setTimeout(() => {
                apiDropdown.style.opacity = '1';
                apiDropdown.style.transform = 'translateY(0)';
            }, 10);
        }
    }

    // 打开模态框
    function openModal() {
        apiModal.classList.remove('hidden');
        // 添加动画效果
        setTimeout(() => {
            modalContent.classList.remove('scale-95', 'opacity-0');
            modalContent.classList.add('scale-100', 'opacity-100');
        }, 10);
    }

    // 关闭模态框
    function closeModalFunc() {
        modalContent.classList.remove('scale-100', 'opacity-100');
        modalContent.classList.add('scale-95', 'opacity-0');
        setTimeout(() => {
            apiModal.classList.add('hidden');
        }, 300);
    }

    // 发送聊天消息
    async function sendMessage(message) {
        if (!message.trim()) return;

        // 添加用户消息到聊天界面
        addMessageToChat('user', message);

        // 清空输入框
        userInput.value = '';
        userInput.style.height = 'auto';

        // 添加AI正在思考的消息
        const thinkingId = addMessageToChat('ai', '<div class="animate-pulse">思考中...</div>', true);

        try {
            // 获取当前选中的API
            const currentApi = apiList[currentApiIndex];
            const apiUrl = `http://localhost:${currentApi.port}${currentApi.path}`;

            // 构建完整的URL，包含查询参数
            const fullUrl = `${apiUrl}?message=${encodeURIComponent(message)}`;

            // 发送GET请求
            const response = await fetch(fullUrl, {
                method: 'GET',
                headers: {
                    'Accept': 'text/event-stream, application/json, text/plain',
                },
            });

            // 移除"思考中"消息
            removeMessageFromChat(thinkingId);

            if (!response.ok) {
                throw new Error(`HTTP错误，状态码: ${response.status}`);
            }

            // 检查响应是否为流
            const contentType = response.headers.get('content-type');

            if (contentType && contentType.includes('text/event-stream')) {
                // 处理流式响应
                const messageId = addMessageToChat('ai', '', false);
                const messageElement = document.getElementById(messageId);
                const reader = response.body.getReader();
                const decoder = new TextDecoder();
                let content = '';

                // 检查是否是图片流
                let isImage = false;
                let imageChunks = [];

                while (true) {
                    const { done, value } = await reader.read();

                    if (done) {
                        if (isImage) {
                            // 完成图片流处理
                            const blob = new Blob(imageChunks, { type: 'image/png' });
                            const imgUrl = URL.createObjectURL(blob);
                            const imgElement = document.createElement('img');
                            imgElement.src = imgUrl;
                            imgElement.className = 'max-w-full rounded-lg my-2';
                            imgElement.alt = 'AI生成的图片';

                            // 清除临时内容并添加图片
                            const messageContent = messageElement.querySelector('div.bg-neutral-50');
                            messageContent.innerHTML = '';
                            messageContent.appendChild(imgElement);
                        }
                        break;
                    }

                    // 解码数据
                    const chunk = decoder.decode(value, { stream: true });

                    // 简单判断是否是图片流（根据实际API响应调整）
                    if (chunk.startsWith('data:image')) {
                        isImage = true;
                        // 提取base64数据
                        const base64Data = chunk.split(',')[1];
                        const binaryData = atob(base64Data);
                        const arrayBuffer = new ArrayBuffer(binaryData.length);
                        const uint8Array = new Uint8Array(arrayBuffer);

                        for (let i = 0; i < binaryData.length; i++) {
                            uint8Array[i] = binaryData.charCodeAt(i);
                        }

                        imageChunks.push(uint8Array);
                    } else {
                        // 文本流处理
                        content += chunk;

                        // 更新消息内容
                        const messageContent = messageElement.querySelector('div.bg-neutral-50');
                        messageContent.innerHTML = content;

                        // 滚动到底部
                        chatContainer.scrollTop = chatContainer.scrollHeight;
                    }
                }
            } else {
                // 处理普通响应
                const data = await response.text();
                addMessageToChat('ai', data);
            }
        } catch (error) {
            // 移除"思考中"消息
            removeMessageFromChat(thinkingId);

            // 显示错误消息
            addMessageToChat('error', `发送请求失败: ${error.message}`);
            console.error('API请求错误:', error);
        }
    }

    // 添加消息到聊天界面
    function addMessageToChat(sender, content, isTemp = false) {
        const messageId = `msg-${Date.now()}-${Math.floor(Math.random() * 1000)}`;
        let avatar, bgColor, messageClass;

        if (sender === 'user') {
            avatar = '<i class="fa fa-user"></i>';
            bgColor = 'bg-primary text-white';
            messageClass = 'ml-auto';
        } else if (sender === 'ai') {
            avatar = '<i class="fa fa-robot"></i>';
            bgColor = 'bg-neutral-50 text-neutral-700';
            messageClass = '';
        } else if (sender === 'error') {
            avatar = '<i class="fa fa-exclamation-triangle"></i>';
            bgColor = 'bg-red-50 text-red-700';
            messageClass = '';
        }

        const messageHTML = `
        <div id="${messageId}" class="flex items-start space-x-3 ${isTemp ? 'opacity-70' : ''}">
          <div class="w-8 h-8 rounded-full ${sender === 'user' ? 'bg-primary/10 text-primary' : sender === 'ai' ? 'bg-neutral-200 text-neutral-600' : 'bg-red-100 text-red-500'} flex items-center justify-center">
            ${avatar}
          </div>
          <div class="flex-1 ${messageClass}">
            <div class="${bgColor} rounded-lg p-3 break-words">
              ${content}
            </div>
          </div>
        </div>
      `;

        chatContainer.insertAdjacentHTML('beforeend', messageHTML);
        chatContainer.scrollTop = chatContainer.scrollHeight;

        return messageId;
    }

    // 从聊天界面移除消息
    function removeMessageFromChat(messageId) {
        const messageElement = document.getElementById(messageId);
        if (messageElement) {
            messageElement.remove();
        }
    }

    // 自动调整文本框高度
    function adjustTextareaHeight() {
        userInput.style.height = 'auto';
        userInput.style.height = (userInput.scrollHeight) + 'px';
    }

    // 初始化
    function init() {
        // 渲染API列表
        renderApiList();

        // API选择器点击事件
        apiSelectorButton.addEventListener('click', (e) => {
            e.stopPropagation();
            toggleApiDropdown();
        });

        // 点击外部关闭API下拉菜单
        document.addEventListener('click', (e) => {
            if (!apiSelectorContainer.contains(e.target)) {
                apiDropdown.classList.add('hidden');
            }
        });

        // 添加API按钮点击事件
        addApiButton.addEventListener('click', addApi);

        // 关闭模态框事件
        closeModal.addEventListener('click', closeModalFunc);
        cancelApiForm.addEventListener('click', closeModalFunc);

        // 点击模态框外部关闭
        apiModal.addEventListener('click', (e) => {
            if (e.target === apiModal) {
                closeModalFunc();
            }
        });

        // API表单提交事件
        apiForm.addEventListener('submit', (e) => {
            e.preventDefault();

            const apiId = document.getElementById('apiId').value;
            const name = document.getElementById('apiName').value.trim();
            const port = document.getElementById('apiPort').value.trim();
            const path = document.getElementById('apiPath').value.trim();

            if (!name || !port || !path) {
                alert('请填写所有字段');
                return;
            }

            if (apiId === '') {
                // 添加新API
                apiList.push({
                    id: Date.now(),
                    name,
                    port: parseInt(port),
                    path
                });
            } else {
                // 更新现有API
                apiList[parseInt(apiId)] = {
                    ...apiList[parseInt(apiId)],
                    name,
                    port: parseInt(port),
                    path
                };
            }

            renderApiList();
            closeModalFunc();
        });

        // 聊天表单提交事件
        chatForm.addEventListener('submit', (e) => {
            e.preventDefault();
            sendMessage(userInput.value);
        });

        // 文本框输入事件 - 自动调整高度
        userInput.addEventListener('input', adjustTextareaHeight);

        // 文本框按键事件 - 处理Enter发送消息
        userInput.addEventListener('keydown', (e) => {
            if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                sendMessage(userInput.value);
            }
        });

        // 初始化文本框高度
        adjustTextareaHeight();
    }

    // 启动应用
    document.addEventListener('DOMContentLoaded', init);
</script>
</body>
</html>